home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsII / InterPhong.c < prev    next >
Text File  |  1992-06-16  |  5KB  |  218 lines

  1. /******************************************************
  2. InterPhong shading for Scan-line rendering algorithms 
  3.  
  4. InterPhong shading has been used for rendering the 
  5. synthetic actors Marilyn
  6. Monroe and Humphrey Bogart in the film "Rendez-vous 
  7. a Montreal" directed by Nadia Magnenat Thalmann and 
  8. Daniel Thalmann, 1987
  9.  
  10. *******************************************************/
  11.  
  12. #include <math.h>
  13. #include "GraphicsGems.h"
  14.  
  15. #define RESANTI    3839
  16. #define NBMAXSOURCES    10
  17. #define SQRT3_2    3.464101615
  18. #define NIL     0
  19.  
  20. typedef struct  {
  21.     double r, g, b;
  22. } Colors;
  23.  
  24. typedef struct  {
  25.     Colors coul;
  26.     double w, n;
  27. } RecCoul;
  28.  
  29. /*    Declaration of types used for the datastructures that 
  30. represent the information of a figure for the treatment by 
  31. scanline ( software rendering )
  32.  */
  33.  
  34. typedef struct blocedge { 
  35.     struct blocedge *edsuiv;    /* next edge in the list */
  36.     struct blocpoly *ptpoly1, *ptpoly2;    /* 
  37. polygons sharing this edge */
  38.     double x, dx;    /* Xmin and Xdelta */
  39.     double z, dz;    /* Zmin and Zdelta */
  40.     double ymax;    /* maximum Y of edge */
  41.     double nx, dnx, ny, dny, nz, dnz;
  42.     double px, dpx, py, dpy, pz, dpz;
  43. } BlockEdge;
  44.  
  45. typedef struct blocpoly {
  46.     struct blocpoly *polsuiv;    /* next polygon in the list */
  47.     struct T_ptedge *ptlisttrie;
  48.     RecCoul refl;    /* polygon characteristics color, spec.
  49.              coeff., ... */
  50.     Colors coulpoly;    /* polygon shading */
  51.     Vector3 normalctri;
  52.     double bias, tension;
  53. } BlockPoly;
  54.  
  55. typedef struct T_ptedge {
  56.     BlockEdge *ptedtrie;
  57.     struct T_ptedge *ptedsuiv;
  58. } PtEdge;
  59.  
  60. /*
  61.  * Declaration of types concerning the calculated image for the
  62.  * current scanline ( Z-buffer )
  63.  */
  64.  
  65. typedef struct scanbuf_el {
  66.     Colors c,     /* final color of this pixel */
  67.            polycolor;    /* initial color of 
  68. visible polygon */
  69. } ScanBufType [RESANTI + 1]; 
  70.  
  71. typedef struct epthbuf_el {
  72.     double depth;    /* depth of opaque 
  73. pixel */
  74. } DepthBufType [RESANTI + 1]; 
  75.  
  76. typedef struct    {
  77.     int    xmin, xmax;
  78. } PosBufType;
  79.  
  80. /*
  81.  * Declaration of data structure types to store light source information 
  82.  */
  83.  
  84. static PosBufType    posbuffer;
  85.  
  86. ScanBufType _scanbuffer;        /* Z-buffer */
  87. DepthBufType _depthbuffer;
  88.  
  89. static
  90. void intphong(nestime, noriginal, bias, tension)
  91. Vector3 *nestime, *noriginal;
  92. double bias, tension;
  93.  
  94. /*
  95.     Purpose: interphong interpolation
  96.     Arguments
  97.     nestime     : estimated normal
  98.     noriginal    : original normal
  99.     bias, tension    : bias and tension 
  100. */
  101.  
  102. {
  103.     double fact;
  104.     Vector3    vtemp;
  105.  
  106.     V3Sub (noriginal, nestime, &vtemp);
  107.     fact = fabs(vtemp.x) + fabs(vtemp.y) + fabs(vtemp.z);
  108.     fact = (fact + bias * (SQRT3_2 - fact)) * tension;
  109.     V3Scale (vtemp,fact*V3Length (vtemp));
  110.     V3Add (nestime, &vtemp,nestime); 
  111.     V3Normalize (nestime);
  112. }
  113.  
  114. /*===========================================================*/
  115.  
  116. static
  117. void shadepoly(ptpoly)
  118. BlockPoly    *ptpoly;
  119.  
  120. /*
  121.     Purpose: shades a polygon on the current scanline
  122.     Arguments
  123.     ptpoly        : polygon to render
  124.     noscline    : current scanline
  125. */
  126.  
  127. {
  128.     BlockEdge    *edge1, *edge2;
  129.     PtEdge    *tripedtrie;
  130.     int        xx;
  131.     double    dxx;
  132.     double    zz, dzz;
  133.     double    diffx;
  134.     double    dnnx, dnny, dnnz;
  135.     Vector3    normal, unitn;
  136.     double    dppx, dppy, dppz;
  137.     Vector3    point;
  138.     Colors    cc;
  139.     RecCoul    ptrefl;
  140.     register struct scanbuf_el    *scanel ;
  141.     register struct depthbuf_el    *depthel ;
  142.  
  143.     tripedtrie = ptpoly->ptlisttrie;
  144.     ptrefl = ptpoly->refl;
  145.     while (tripedtrie != (PtEdge *)NIL) 
  146.     {
  147.         edge1 = tripedtrie->ptedtrie;
  148.         if (tripedtrie->ptedsuiv != (PtEdge *)NIL) 
  149.         {
  150.             tripedtrie = tripedtrie->ptedsuiv;
  151.             edge2 = tripedtrie->ptedtrie;
  152.         } 
  153.         else 
  154.             abort(" Odd number of edges on scanline");
  155.  
  156.         dxx = edge2->x - edge1->x;    /* distance between edges
  157.                            on current scanline */
  158.         if (dxx < 1.0)            /* crossing edges ? */
  159.             dxx = 1.0;
  160.         dxx = 1.0 / dxx;        /* increment per pixel */
  161.         xx = Trunc(edge1->x) + 1;    /* first pixel to be 
  162.                            colored */
  163.         diffx = xx - edge1->x;
  164.  
  165.         dzz = (edge2->z - edge1->z) * dxx;
  166.         zz = edge1->z + dzz * diffx;
  167.  
  168.         if (xx < posbuffer.xmin)
  169.             posbuffer.xmin = xx;
  170.         if (edge2->x > posbuffer.xmax)
  171.             posbuffer.xmax = Trunc(edge2->x);
  172.  
  173.         dnnx = (edge2->nx - edge1->nx) * dxx;
  174.         dnny = (edge2->ny - edge1->ny) * dxx;
  175.         dnnz = (edge2->nz - edge1->nz) * dxx;
  176.         normal.x = (edge1->nx + dnnx * diffx) + dnnx;
  177.         normal.y = (edge1->ny + dnny * diffx) + dnny;
  178.         normal.z = (edge1->nz + dnnz * diffx) + dnnz;
  179.         dppx = (edge2->px - edge1->px) * dxx;
  180.         dppy = (edge2->py - edge1->py) * dxx;
  181.         dppz = (edge2->pz - edge1->pz) * dxx;
  182.         point.x = (edge1->px + dppx * diffx) + dppx;
  183.         point.y = (edge1->py + dppy * diffx) + dppy;
  184.         point.z = (edge1->pz + dppz * diffx) + dppz;
  185.  
  186.         while (xx <= edge2->x) 
  187.         {
  188.             scanel = &_scanbuffer[xx];
  189.             depthel = &_depthbuffer[xx];
  190.  
  191.             if (zz < depthel->depth) 
  192.             {
  193.                 unity(normal, &unitn);
  194.                 intphong(&unitn, &ptpoly->normalctri, 
  195.                     ptpoly->bias, ptpoly->tension);
  196.                 cc = ptpoly->coulpoly;
  197.                 depthel->depth = zz;
  198.                 scanel->polycolor = ptrefl.coul;
  199.                 scanel->c = cc;
  200.             }
  201.             xx = xx + 1;
  202.             zz = zz + dzz;
  203.             normal.x = normal.x + dnnx;
  204.             normal.y = normal.y + dnny;
  205.             normal.z = normal.z + dnnz;
  206.             point.x = point.x + dppx;
  207.             point.y = point.y + dppy;
  208.             point.z = point.z + dppz;
  209.         }
  210.         break ;
  211.         tripedtrie = tripedtrie->ptedsuiv;
  212.     }
  213. }
  214.  
  215.  
  216.  
  217.  
  218.